#![allow(dead_code, unused)]

use chrono::Local;
use ratatui::{
    Frame,
    layout::{Position, Rect},
};
use serde_json::Value;

use crate::components::component::App;

// 美化JSON显示，带缩进
pub fn pretty_json_to_lines(value: &Value, indent: usize) -> Vec<String> {
    let mut lines = Vec::new();
    match value {
        Value::Object(map) => {
            lines.push("{".to_string());
            for (i, (k, v)) in map.iter().enumerate() {
                let comma = if i == map.len() - 1 { "" } else { "," };
                let key_line = format!("{}\"{}\": ", "  ".repeat(indent + 1), k);

                match v {
                    Value::Object(_) | Value::Array(_) => {
                        let nested = pretty_json_to_lines(v, indent + 1);
                        lines.push(format!("{}{}", key_line, nested[0]));
                        lines.extend_from_slice(&nested[1..]);
                        lines.push(format!("{}{}", "  ".repeat(indent), comma));
                    }
                    _ => {
                        lines.push(format!("{}{}{}", key_line, json_to_line(v), comma));
                    }
                }
            }
            lines.push("}".to_string());
        }
        Value::Array(arr) => {
            lines.push("[".to_string());
            for (i, item) in arr.iter().enumerate() {
                let comma = if i == arr.len() - 1 { "" } else { "," };

                match item {
                    Value::Object(_) | Value::Array(_) => {
                        let nested = pretty_json_to_lines(item, indent + 1);
                        lines.push(format!("{}{}", "  ".repeat(indent + 1), nested[0]));
                        lines.extend_from_slice(&nested[1..]);
                        lines.push(format!("{}{}", "  ".repeat(indent), comma));
                    }
                    _ => {
                        lines.push(format!(
                            "{}{}{}",
                            "  ".repeat(indent + 1),
                            json_to_line(item),
                            comma
                        ));
                    }
                }
            }
            lines.push("]".to_string());
        }
        _ => lines.push(json_to_line(value)),
    }
    lines
}

// 单行显示基本类型
fn json_to_line(value: &Value) -> String {
    match value {
        Value::String(s) => format!("\"{s}\""),
        Value::Null => "".to_string(),
        _ => value.to_string(),
    }
}

/// 计算光标在一个会换行的段落中的 (x, y) 位置。
///
/// # Arguments
/// * `text` - 输入框中的完整文本。
/// * `max_width` - 文本框的内部宽度（即 Block 的宽度减去边框）。
///
/// # Returns
/// A tuple `(u16, u16)` a representing the (x, y) coordinates for the cursor.
pub fn get_cursor_position(text: &str, max_width: u16) -> (u16, u16) {
    if max_width == 0 {
        return (0, 0);
    }

    let mut cursor_x = 0;
    let mut cursor_y = 0;

    for c in text.chars() {
        if c == '\n' {
            cursor_y += 1;
            cursor_x = 0;
        } else {
            // 检查是否需要换行
            if cursor_x >= max_width {
                cursor_y += 1;
                cursor_x = 1;
            } else {
                cursor_x += 1;
            }
        }
    }

    (cursor_x, cursor_y)
}

/// 在 TUI 应用中，默认情况下，终端的光标是隐藏的。这是因为如果它一直显示，它会在屏幕上随意地闪烁，非常影响美观
/// set_cursor_position 的作用就是告诉 ratatui：“在这一帧，我需要你把终端的光标显示出来，并把它放到我指定的 (x, y) 坐标上。”
/// 你只应该在你希望用户能够输入文本的时候调用它，比如：
/// ```
/// 1.当用户按 s 进入 "Server Address" 的编辑模式时。
/// 2.当用户按 h 进入 "Headers" 的编辑模式时。
/// ```
/// 在其他所有时间（比如普通模式），你不调用这个方法，光标就会自动保持隐藏。
/// ```
/// 重要： set_cursor_position 的坐标是相对于整个终端窗口左上角 (0, 0) 的绝对坐标，而不是相对于你正在渲染的那个 Rect 的相对坐标。
/// 光标 X = Rect 的 X 坐标 + 边框/内边距 + 已输入文本的长度
/// 光标 Y = Rect 的 Y 坐标 + 边框/内边距
/// ```
pub fn set_cursor_position(f: &mut Frame, x: u16, y: u16) {
    f.set_cursor_position(Position { x, y });
}

pub fn scroll_x_y(app: &mut App, area: Rect) -> (usize, usize) {
    // 计算安全滚动范围
    // 计算可见区域高度
    let visible_height = area.height as usize;

    // 动态调整最大滚动位置
    let max_scroll = if app.received_data.len() > visible_height {
        app.received_data.len() - visible_height
    } else {
        0 // 内容不足一屏时不允许滚动
    };

    // 确保当前滚动位置在合法范围内
    let scroll_position = app.scroll_position.min(max_scroll);
    app.scroll_position = scroll_position; // 更新回app状态

    let end = (scroll_position + visible_height).min(app.received_data.len());

    (scroll_position, end)
}

/// 根据文本内容和容器大小，计算允许的最大滚动行数
pub fn calculate_max_scroll(text: &str, area: Rect) -> usize {
    if text.is_empty() || area.height == 0 {
        return 0;
    }

    let max_width = area.width as usize;
    if max_width == 0 {
        return 0;
    }

    let mut total_lines: usize = 1;
    let mut current_line_width = 0;

    for c in text.chars() {
        if c == '\n' {
            total_lines += 1;
            current_line_width = 0;
        } else if current_line_width >= max_width {
            total_lines += 1;
            current_line_width = 1;
        } else {
            current_line_width += 1;
        }
    }

    let visible_lines = area.height as usize;
    total_lines.saturating_sub(visible_lines)
}

pub fn now() -> String {
    Local::now().format("%F %T").to_string()
}
